import { Reducer } from 'redux';
import { Effect } from './connect.d';

export interface NoticeItem {
    id: string;
    type: string;
    status: string;
}

export interface GlobalModelState {
    collapsed: boolean;
    notices: any[];
    tabs: any[];
    showMore: boolean;
    screen: string;
    isMobile: boolean;
    hasPath: boolean;
}

export interface GlobalModelType {
    namespace: 'global';
    state: GlobalModelState;
    effects: {
        clearNotices: Effect;
        changeNoticeReadState: Effect;
    };
    reducers: {
        changeLayoutCollapsed: Reducer;
        addTab: Reducer;
        resetTab: Reducer;
        setMore: Reducer;
        setScreen: Reducer;
        setPath: Reducer;
        clearPath: Reducer;
        changeScreenSize: Effect;
    };
}

const GlobalModel: GlobalModelType = {
    namespace: 'global',

    state: {
        collapsed: false,
        notices: [],
        tabs: [],
        showMore: false,
        screen: 'md',
        isMobile: false,
        hasPath: false,
    },

    effects: {
        * clearNotices({ payload }, { put, select }) {
            yield put({
                type: 'saveClearedNotices',
                payload,
            });
            const count: number = yield select(state => state.global.notices.length);
            const unreadCount: number = yield select(
                state => state.global.notices.filter((item: any) => !item.read).length,
            );
            yield put({
                type: 'user/changeNotifyCount',
                payload: {
                    totalCount: count,
                    unreadCount,
                },
            });
        },
        * changeNoticeReadState({ payload }, { put, select }) {
            const notices: NoticeItem[] = yield select(state => state.global.notices.map((item) => {
                const notice: any = { ...item };
                if (notice.id === payload) {
                    notice.read = true;
                }
                return notice;
            }));

            yield put({
                type: 'saveNotices',
                payload: notices,
            });

            yield put({
                type: 'user/changeNotifyCount',
                payload: {
                    totalCount: notices.length,
                    unreadCount: notices.filter((item: any) => !item.read).length,
                },
            });
        },
    },

    reducers: {
        changeLayoutCollapsed(state, action) {
            return ({
                ...state,
                collapsed: action.payload,
            });
        },
        addTab(state, { payload }) {
            const { tabs } = state;
            if (payload.isTopMenu) {
                const pos = tabs.findIndex((_tab: any) => _tab.name === payload.name);
                if (pos !== -1) {
                    tabs[pos].url = payload.url;
                } else {
                    tabs.push({
                        name: payload.name,
                        url: payload.url,
                    });
                }
            } else {
                const pos = tabs.findIndex((_tab: any) => _tab.url === payload.url);
                if (pos === -1) {
                    const { pathname, search } = window.location;
                    const currentPos = tabs.findIndex((_tab: any) => _tab.url === pathname + search);
                    tabs.splice(currentPos + 1, 0, payload);
                }
            }

            return {
                ...state,
                tabs,
            };
        },
        resetTab(state, { payload }) {
            return {
                ...state,
                tabs: payload.tabs,
            };
        },
        setMore(state, { payload }) {
            return {
                ...state,
                showMore: payload.isShow,
            };
        },
        setScreen(state, { payload }) {
            return {
                ...state,
                screen: payload.screen,
            };
        },
        setPath(state) {
            return {
                ...state,
                hasPath: true,
            };
        },
        clearPath(state) {
            return {
                ...state,
                hasPath: false,
            };
        },
        changeScreenSize(state, { payload }) {
            return {
                ...state,
                isMobile: payload,
            };
        },
    },
};

export default GlobalModel;
